import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DeepPartial, FindOptionsWhere, Repository } from 'typeorm';
import { CardRecord } from './models/cardRecord.entity';
import { ProductService } from '../product/product.service';
import { CardType } from '../card/dto/card.type';
import { cardTypeType } from '../card/models/card.entity';
import dayjs from 'dayjs';
import { CardRecordType } from './dto/cardRecord.type';

@Injectable()
export class CardRecordService {
  constructor(
    @InjectRepository(CardRecord)
    private readonly CardRecordRepository: Repository<CardRecord>,
    private readonly productService: ProductService,
  ) {}

  // 添加多个用户消费卡
  async addCardRecordw(
    productId: string,
    orgId: string,
    userId: string,
  ): Promise<boolean> {
    const crs = [];
    const product = await this.productService.findById(productId);
    const cards = JSON.parse(product.cards) as CardType[];
    for (const card of cards) {
      const currentDate = new Date();
      const currentDay = currentDate.getDate();
      currentDate.setDate(currentDay + Number(card.validityDay));
      const cardRecord = new CardRecord();
      cardRecord.startTime = new Date().toISOString();
      cardRecord.endTime = currentDate.toISOString();
      cardRecord.residueTime = card.time;
      cardRecord.card = JSON.stringify(card);
      cardRecord.orgId = orgId;
      cardRecord.studentId = userId;
      cardRecord.courseId = card.courseId;
      cardRecord.productId = productId;
      cardRecord.createdBy = userId;
      // 创建实例
      const res = await this.CardRecordRepository.create(cardRecord);
      crs.push(res);
    }
    // 真正添加实例到数据库
    const res = await this.CardRecordRepository.save(crs);
    return !!res && !!product;
  }

  async create(entity: DeepPartial<CardRecord>): Promise<boolean> {
    const res = await this.CardRecordRepository.save(
      this.CardRecordRepository.create(entity),
    );
    return !!res;
  }

  async findById(id: string): Promise<CardRecord> {
    return this.CardRecordRepository.findOne({
      where: {
        id,
      },
    });
  }

  async updateById(
    id: string,
    entity: DeepPartial<CardRecord>,
  ): Promise<boolean> {
    const existEntity = await this.findById(id);
    if (!existEntity) {
      return false;
    }
    Object.assign(existEntity, entity);
    const res = await this.CardRecordRepository.save(existEntity);
    return !!res;
  }

  async findCardRecords({
    start,
    length,
    where,
  }: {
    start: number;
    length: number;
    where: FindOptionsWhere<CardRecord>;
  }): Promise<[CardRecord[], number]> {
    return this.CardRecordRepository.findAndCount({
      take: length,
      skip: start,
      where,
      order: {
        id: 'DESC',
      },
    });
  }

  async deleteById(id: string, userId: string): Promise<boolean> {
    const res1 = await this.CardRecordRepository.update(id, {
      deletedBy: userId,
    });
    if (res1) {
      const res = await this.CardRecordRepository.softDelete(id);
      if (res.affected > 0) {
        return true;
      }
    }
    return false;
  }

  // 获取有效的消费卡
  async findNormalCardRecords(studentId: string): Promise<CardRecord[]> {
    const [res] = await this.CardRecordRepository.findAndCount({
      where: {
        studentId,
      },
      order: {
        id: 'DESC',
      },
    });
    const newCardRecords = [];
    for (const item of res) {
      const card = JSON.parse(item.card);
      switch (card.type) {
        case cardTypeType.TIME: {
          if (item.residueTime !== 0) newCardRecords.push(item);
          break;
        }
        case cardTypeType.DURATION: {
          if (dayjs().isBefore(item.endTime)) newCardRecords.push(item);
          break;
        }
      }
    }
    return newCardRecords;
  }

  async findNormalCardRecordsByCourse(
    studentId: string,
    courseId: string,
  ): Promise<CardRecordType[]> {
    const [res] = await this.CardRecordRepository.findAndCount({
      where: {
        studentId,
        courseId,
      },
      order: {
        id: 'DESC',
      },
    });
    const newCardRecords = [];
    for (const item of res) {
      const card = JSON.parse(item.card);
      switch (card.type) {
        case cardTypeType.TIME: {
          if (item.residueTime !== 0)
            newCardRecords.push({
              ...item,
              startTime: item.startTime.toLocaleString(),
              endTime: item.endTime.toLocaleString(),
            });
          break;
        }
        case cardTypeType.DURATION: {
          if (dayjs().isBefore(item.endTime))
            newCardRecords.push({
              ...item,
              startTime: item.startTime.toLocaleString(),
              endTime: item.endTime.toLocaleString(),
            });
          break;
        }
      }
    }
    return newCardRecords;
  }
}
